﻿#include <iostream>

using namespace std;


class Base
{
public:
	virtual void func1() { cout << "Base::func1" << endl; }
	virtual void func2() { cout << "Base::func2" << endl; }
	void func5() { cout << "Base::func5" << endl; }
protected:
	int a = 1;
};
class Derive : public Base
{
public:
	// 重写基类的func1
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func1" << endl; }
	void func4() { cout << "Derive::func4" << endl; }
protected:
	int b = 2;
};

//int main()
//{
//	Base b;
//	Derive d;
//	return 0;
//}
//////////////////
int main()
{
	int i = 0;
	static int j = 1;
	int* p1 = new int;
	const char* p2 = "xxxxxxxx";
	printf("栈:%p\n", &i);
	printf("静态区:%p\n", &j);
	printf("堆:%p\n", p1);
	printf("常量区:%p\n", p2);
	Base b;
	Derive d;
	Base* p3 = &b;
	Derive* p4 = &d;
	printf("Person虚表地址:%p\n", *(int*)p3);
	printf("Student虚表地址:%p\n", *(int*)p4);
	printf("虚函数地址:%p\n", &Base::func1);
	printf("普通函数地址:%p\n", &Base::func5);
	return 0;
}
//////////////////////////////
//运⾏结果:
//栈:003DF7B0
//静态区 : 00C1D000
//堆 : 008237B8
//常量区 : 00C1AB94
//Person虚表地址 : 00C1AB34
//Student虚表地址 : 00C1AB74
//虚函数地址 : 00C11488
//普通函数地址 : 00C114C4

//class Person
//{
//public:
//	virtual void BuyTicket()
//	{
//		cout << "买票-全价" << endl;
//	}
//};
//class Student : public Person
//{
//public:
//	virtual void BuyTicket()
//	{
//		cout << "买票-打折" << endl;
//	}
//};
//class Soldier : public Person
//{
//public:
//	virtual void BuyTicket()
//	{
//		cout << "买票-优先" << endl;
//	}
//};
//void Func(Person* ptr)
//{
//	// 这⾥可以看到虽然都是Person指针Ptr在调⽤BuyTicket
//	// 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
//	ptr->BuyTicket();
//}
//int main()
//{
//	// 其次多态不仅仅发⽣在派⽣类对象之间，多个派⽣类继承基类，重写虚函数后
//	// 多态也会发⽣在多个派⽣类之间。
//	Person ps;
//	Student st;
//	Soldier sr;
//	Func(&ps);
//	Func(&st);
//	Func(&sr);
//	return 0;
//}

//class Base
//{ 
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//protected:
//	int _b = 1;
//	char _ch = 'x';
//};
//int main()
//{
//	Base b;
//	cout << sizeof(b) << endl;
//	return 0;
//}

//class Base //final
//{
//public:
//	void func5()
//	{
//		cout << "Base::func5" << endl;
//	}
//protected:
//	int a = 1;
//private:
//	// C++98的⽅法
//	/*Base()
//	{}*/
//};
//
//class Derive :public Base
//{
//	void func4()
//	{
//		cout << "Derive::func4" << endl;
//	}
//protected:
//	int b = 2;
//};
//int main()
//{
//	Base b;
//	Derive d;
//	return 0;
//}
//

//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name = "xz"; // 姓名
//};
//
//class Student : public Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	int _stuNum = 999; // 学号
//};
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl;
//}
//int main()
//{
//	Person p;
//	Student s;
//	// 编译报错：error C2248: “Student::_stuNum”: ⽆法访问 protected 成员
//	// 解决⽅案：Display也变成Student 的友元即可
//	Display(p, s);
//	return 0;
//}


//class Car
//{
//public:
//	virtual void Dirve()
//	{}
//};
//class Benz :public Car
//{
//public:
//	virtual void Dirve() override
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//int main()
//{
//	return 0;
//}


//
//class A
//{
//public:
//	virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//class B : public A
//{
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//// 只有派⽣类Student的析构函数重写了Person的析构函数，下⾯的delete对象调⽤析构函数，才能构成多态，才能保证p1和p2指向的对象正确的调⽤析构函数。
//int main()
//{
//	A* p1 = new A;
//	A* p2 = new B;
//	delete p1;
//	delete p2;
//	return 0;
//}


//class Person
//{
//public:
//	virtual void BuyTicket()
//	{
//		cout << "买票-全价" << endl;
//	}
//};
//class Student : public Person
//{
//public:
//	virtual void BuyTicket()
//	{
//		cout << "买票-打折" << endl;
//	}
//};
//void Func(Person* ptr)
//{
//	// 这⾥可以看到虽然都是Person指针Ptr在调⽤BuyTicket
//	// 但是跟ptr没关系，⽽是由ptr指向的对象决定的。
//	ptr->BuyTicket();
//}
//int main()
//{
//	Person ps;
//	Student st;
//	Func(&ps);
//	Func(&st);
//	return 0;
//}

//
//class Animal
//{
//public:
//	virtual void talk() const
//	{}
//};
//class Dog : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "汪汪" << std::endl;
//	}
//};
//class Cat : public Animal
//{
//public:
//	virtual void talk() const
//	{
//		std::cout << "(>^ω^<)喵" << std::endl;
//	}
//};
//void letsHear(const Animal& animal)
//{
//	animal.talk();
//}
//int main()
//{
//	Cat cat;
//	Dog dog;
//	letsHear(cat);
//	letsHear(dog);
//	return 0;
//}